05. 文本:子查询格式

子查询格式

在编写 子查询 时,查询很容易就看起来很复杂。为了便于阅读,其实日后经常只是你自己要阅读:

要记住的重要事项是,在使用子查询时,要让读者能够轻松地判断查询的哪个部分将一起执行。大部分人的做法是按照某种方式缩进子查询,上一页面的解决方案就是这么做的。

这节课的示例缩进很明显,一直到小括号。如果你嵌套了很多的子查询,则不适用,一般法则就是思考下如何以便于阅读的方式编写查询。下面给出了以多种方式编写同一查询的示例。你会发现,某些示例明显比其他的容易阅读。


格式糟糕的查询

虽然这些格式糟糕的查询和格式清晰的查询一样会执行,但是却不容易让人理解查询的作用!

以下是第一个示例,根本无法判断查询的作用:

SELECT * FROM (SELECT DATE_TRUNC('day',occurred_at) AS day, channel, COUNT(*) as events FROM web_events GROUP BY 1,2 ORDER BY 3 DESC) sub;

下面的第二个示例不是太糟糕,但是你会发现最后一个示例依然更容易读懂。

SELECT *
FROM (
SELECT DATE_TRUNC('day',occurred_at) AS day,
channel, COUNT(*) as events
FROM web_events
GROUP BY 1,2
ORDER BY 3 DESC) sub;

格式清晰的查询

与之前的示例相比,在这个格式清晰的示例中,我们很容易就看出要从哪个表格中获取数据。此外,如果在子查询后面有 GROUP BY ORDER BY WHERE HAVING 或任何其他语句,则按照外部查询的同一级别缩进,正如最后一个示例所显示的,它是上个练习的最后一个解决方案。

SELECT *
FROM (SELECT DATE_TRUNC('day',occurred_at) AS day,
                channel, COUNT(*) as events
      FROM web_events 
      GROUP BY 1,2
      ORDER BY 3 DESC) sub;

下面的查询很相似,但是向外部查询应用了其他逻辑,因此按照外部查询的级别缩进。而内部查询逻辑的缩进级别与内部表格匹配。

SELECT *
FROM (SELECT DATE_TRUNC('day',occurred_at) AS day,
                channel, COUNT(*) as events
      FROM web_events 
      GROUP BY 1,2
      ORDER BY 3 DESC) sub
GROUP BY channel
ORDER BY 2 DESC;

最后两个查询容易读懂多了!